#!/usr/bin/env python
# -*- coding: utf-8 -*-


import json
import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder

import logging
_logger = logging.getLogger(__name__)


def ret(r):
    # print('status_code:', r.status_code)
    # print('raw:', r.raw.read())
    # print('content:', r.content)
    # print('text:', r.text)
    print('headers:', r.headers)
    print('headers:', type(r.headers))


# print('t1')
# t1()

def import_rpc(url, data,  sid=None):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0',
        'Referer': url,
    }

    multipart_encoder = MultipartEncoder(
        fields=data,
        boundary='abcdefg'
    )

    headers['Content-Type'] = multipart_encoder.content_type

    headers.update({'X-Openerp-Session-Id': sid})

    rspd = requests.post(url,
                         data=multipart_encoder,
                         #  files=files,
                         headers=headers,
                         )
    # ret(rspd)

    return rspd.text


def export_rpc(url, data, sid=None):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0',
        'Referer': url,
    }

    multipart_encoder = MultipartEncoder(
        fields=data,
        boundary='abcdefg'
    )

    headers['Content-Type'] = multipart_encoder.content_type

    headers.update({'X-Openerp-Session-Id': sid})

    # print('rawrpc,', headers)
    rspd = requests.post(url,
                         data=multipart_encoder,
                         headers=headers,
                         )

    constent = rspd.content
    resp_headers = rspd.headers

    print('headers:', resp_headers)
    filename = resp_headers['content-disposition'][29:]
    filetype = resp_headers['content-type']

    return {'filetype': filetype, 'filename': filename, 'data': constent}


def jsonrpc(uri, data=None, params=None, sid=None, client=None, is_auth=None):
    headers = {"content-type": "application/json"}
    data1 = {"jsonrpc": "2.0",
             "method": "call",
             "id": 123,
             "params": data and data or {}
             }

    params1 = params and params.copy() or {}
    if sid:
        # params1.update({'session_id': sid})
        headers.update({'X-Openerp-Session-Id': sid})

    if not client:
        client = requests

    rspd = client.post(uri, params=params1,
                       data=json.dumps(data1),
                       headers=headers,
                       verify=False)
    # print(rspd)
    # ret(rspd)

    content = json.loads(rspd.content)
    result = content.get('result', {})

    error = content.get('error', {})

    if error:
        print(uri, data, sid)
        print(error)

        return None

    def get_cookie(headers):
        cookie = headers['Set-Cookie']
        return cookie

    def get_sid(cookie):
        cookie2 = cookie.split(';')
        sid = cookie2[0]
        sid = sid.split('=')
        sid = sid[1]
        return sid

    if is_auth:
        cookie = get_cookie(rspd.headers)
        sid = get_sid(cookie)

        return {
            'result': result,
            'cookie': cookie,
            'sid': sid
        }

    return json.loads(rspd.content).get('result', {})


class RPC(object):
    def __init__(self, host, db):
        self.host = host
        self.db = db
        self.sid = None
        self.session = None

    @property
    def version(self):
        server_version_info = self.session['server_version_info']
        # print(server_version_info)
        return server_version_info[0]

    def t1(self):
        headers = {"content-type": "application/json",
                   "credentials": "include"}
        uri = self.host + '/api/test1'
        params = {}
        data = {}
        rspd = requests.post(uri, params=params,
                             data=json.dumps(data),
                             headers=headers)

        ret(rspd)

    def get_session_info(self):
        url = self.host + '/web2/session/get_session_info'
        result = jsonrpc(url, {}, sid=self.sid)
        return result

    def session_check(self):
        url = self.host + '/web2/session/check'
        result = jsonrpc(url, {}, sid=self.sid)
        return result

    def authenticate(self, user, psw):
        url = self.host + '/web2/session/authenticate'

        try:
            rspd = jsonrpc(
                url, {'db': self.db, 'login': user, 'password': psw}, is_auth=1)
            self.sid = rspd.get('sid')
            result = rspd.get('result')
            self.session = result
            return result

        except Exception as e:
            _logger.warning('Error connect server, %s' % str(e))

            return None

    def web_dataset_search_read(self, model, domain=None, fields=False, offset=0, limit=False,
                                sort=None, context=None):
        # print('xxxxx, args, kwargs', model, args, kwargs)

        URI_API = self.host + '/web2/dataset/search_read'

        return jsonrpc(URI_API, {'model': model, 'domain': domain, 'fields': fields,
                                 'offset': offset, 'limit': limit, 'sort': sort,
                                 'context': context or {}}, sid=self.sid)

    def web_dataset_call_kw(self, model, method, *args, **kwargs):
        # print('xxxxx, args, kwargs', model, method, args, kwargs)

        URI_API = self.host + '/web2/dataset/call_kw/' + model + '/' + method
        return jsonrpc(URI_API, {
            'model': model, 'method': method,
            'args': args, 'kwargs': kwargs}, sid=self.sid)

    def xlsx_export(self, data):
        url = '/web/export/csv'
        return self.base_export(url, data)

    def csv_export(self, data):
        url = '/web/export/xlsx'
        return self.base_export(url, data)

    def base_export(self, url, data):
        url = self.host + url
        session = self.session
        csrf_token = session['csrf_token']
        token = 'dummy-because-api-expects-one'
        data2 = {
            'data':  json.dumps(data),
            'token': token,
            'csrf_token': csrf_token
        }

        # print('data2', data2)

        return export_rpc(url, data2, sid=self.sid)

    def base_import_set_file(self, import_id, fp):
        file_types = {
            'csv': 'text/csv',
            'xls': 'application/vnd.ms-excel',
            'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        }

        import os
        file_name = os.path.basename(fp.name)
        file_type = file_name.split('.')[-1]
        file_type = file_types.get(file_type, 'text/csv')

        url = self.host + '/base_import/set_file'
        session = self.session
        csrf_token = session['csrf_token']

        data = {
            'csrf_token': csrf_token,
            'import_id': str(import_id),
            'file':  (file_name, fp, file_type),
        }

        return import_rpc(url, data,  sid=self.sid)

    # def execute(self, model, method, *args, **kwargs):
    #     # print('xxxxx, args, kwargs', model, method, args, kwargs)

    #     URI_API = self.host + '/api/call'
    #     return jsonrpc(URI_API, {'model': model, 'method': method,
    #                              'args': args, 'kwargs': kwargs}, sid=self.sid)

    # def call_api(self, url, **kw):
    #     url = self.host + url
    #     kw2 = {
    #         'db': self.db
    #     }
    #     kw2.update(kw)
    #     result = jsonrpc(url, kw2, sid=self.sid)
    #     return result

    def t2(self, url, model=None):
        headers = {"content-type": "application/json",
                   "credentials": "include"}
        uri = self.host + url
        params = {}
        data = {
            'params': {
                'model': model,
                'fields': ['name']
            }
        }

        rspd = requests.get(uri, params=params,
                            data=json.dumps(data),
                            headers=headers)

        ret(rspd)


def test_1():

    HOST = 'http://192.168.56.101:8069'
    SERVER = 'SL2'
    rpc = RPC(HOST, SERVER)

    session_id = 'db9c386675a3db4abc99969d8effc9e4f163e08d'

    url = '/web/dataset/search_read' + '?session_id=' + session_id

    # ss = jsonrpc(url)

    rpc.t2(url, model='res.partner')

    # print(ss)


def test_rpc():
    HOST = 'http://192.168.56.100:8069'
    SERVER = 'erp'
    rpc = RPC(HOST, SERVER)

    user = 'admin'
    psw = '123456'

    print('-----', )
    session_info = rpc.authenticate(user, psw)
    # print('session_info 1 ', rpc.sid)
    # print('session_info 1 ', rpc.session)
    # print('session_info 1 ', session_info)

    print('-----', )
    session_info = rpc.get_session_info()
    # print('session_info 2', session_info)

    model = 'res.partner'
    method = 'search'
    domain = []
    args = [domain]
    kwargs = {}

    # print('-----', )
    # res = rpc.web_dataset_search_read(model, domain, fields=['name'])
    # print(res)

    print('-----', )
    res = rpc.web_dataset_call_kw(model, 'search', [])
    # res = rpc.web_dataset_call_kw(model, 'read', 1, fields=['name'])
    print(res)

    # res = rpc.execute('res.partner', 'search', *args,  **kwargs)
    # print('execute call, model, method, args, kwargs, res: ',
    #       model, method, args, kwargs, res)


if __name__ == '__main__':
    test_rpc()
    pass
